package edu.xidian.onlinedocument.repository;

import edu.xidian.onlinedocument.entity.OperationData;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Repository
public interface OperationDataJPARepository  extends JpaRepository<OperationData, Integer>, JpaSpecificationExecutor<OperationData> {

    /**
     * exists
     */
    boolean existsOperationDataByOpId(int opId);

    boolean existsOperationDataByDocId(int docId);

    boolean existsOperationDataByOpName(String opName);

    boolean existsOperationDataByOpIdAndDocId(int opId, int docId);

    boolean existsOperationDataByOpRevision(int opVersion);

    /**
     * 查询某文档的某版本操作是否存在
     * @param docId 文档id
     * @param opVersion 操作的版本号
     * @return boolean
     */
    boolean existsOperationDataByDocIdAndOpRevision(int docId, int opVersion);

    /**
     * 获取某文档的一系列操作，升序排序，操作id从小到大（默认就是ASC）
     * @param docId docId
     * @return List<OperationData>
     */
    List<OperationData> findAllByDocIdOrderByOpIdAsc(int docId);

    /**
     * 获取某文档的一系列同名操作，升序排序，操作id从小到大
     * @param docId docId
     * @param opName 操作名称（如"retain" “insert” "delete"）
     * @return List<OperationData>
     */
    List<OperationData> findAllByDocIdAndOpNameOrderByOpIdAsc(int docId, String opName);

    /**
     * 获取某文档的某版本操作，升序排序，操作id从小到大
     * @param docId docId
     * @param opVersion 操作的版本
     * @return List<OperationData>
     */
    List<OperationData> findAllByDocIdAndOpRevisionOrderByOpIdAsc(int docId, int opVersion);

    /**
     * 根据id查询某操作
     * @param opId 操作id
     * @return OperationData
     */
    OperationData findAllByOpId(int opId);

    /**
     * save
     */
    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Error.class})
    <S extends OperationData> List<S> saveAllAndFlush(Iterable<S> entities);

    /**
     * delete
     */
    @Transactional(rollbackFor = {RuntimeException.class, Error.class})
    @Modifying
    int deleteOperationDataByOpId(int opId);

    @Transactional(rollbackFor = {RuntimeException.class, Error.class})
    @Modifying
    int deleteAllByDocId(int docId);

    @Transactional(rollbackFor = {RuntimeException.class, Error.class})
    @Modifying
    int deleteAllByDocIdAndOpRevision(int docId, int opVersion);
}
